/* SPI Master Half Duplex nand example.

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include "spi_w25n01gvzeig.h"
#include "uffs_api.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "esp_log.h"
#include <string.h>



static const char TAG[] = "main";
#define UFFS_MOUNT_POINT "/uffs"
void test_uffs1(void)
{
    int fd = -1;
    const char * write_data = "hello world!";
    uint8_t read_buf[32] = {0};

    printf("prepare write data[%s]\r\n",write_data);
    fd = uffs_open("/test.txt", (UO_RDWR|UO_CREATE|UO_TRUNC));
    if (fd < 0)
    {   
        ESP_LOGE(TAG,"test.txt open error \r\n"); 
        return;
    }
    uffs_write(fd, write_data, strlen(write_data));
    uffs_close(fd);
    fd = -1;
    uffs_rename("/test.txt", "/test1.txt");

    printf("prepare read data\r\n");

    fd = uffs_open("/test1.txt", (UO_RDONLY));
    if (fd < 0)
    {   
        ESP_LOGE(TAG,"test.txt open error \r\n"); 
        return;
    }
    int rsize = uffs_read(fd, read_buf, 32);
    printf("read %d data[%s]\r\n",rsize,read_buf);
    uffs_close(fd);
    uffs_remove("/test1.txt");
}


void test_uffs(void)
{
    FILE* fd = NULL;
    const char * write_data = "hello world!";
    uint8_t read_buf[32] = {0};
    printf("prepare write data[%s]\r\n",write_data);
    fd = fopen(UFFS_MOUNT_POINT"/test.txt", "a+");
    if (fd == NULL)
    {   
        ESP_LOGE(TAG,"test.txt open error \r\n"); 
        return;
    }
    fwrite(write_data, strlen(write_data),1,fd);
    fclose(fd);
    fd = NULL;
    struct stat st;
    if (stat(UFFS_MOUNT_POINT"/test1.txt", &st) == 0) {
        // Delete it if it exists
        unlink(UFFS_MOUNT_POINT"/test1.txt");
        printf("delete test1.txt \r\n");
    }
    if (rename(UFFS_MOUNT_POINT"/test.txt", UFFS_MOUNT_POINT"/test1.txt") != 0) {
        printf("Rename failed\r\n");
        return;
    }

    printf("prepare read data\r\n");

    fd = fopen(UFFS_MOUNT_POINT"/test1.txt", "r");
    if (fd == NULL)
    {   
        ESP_LOGE(TAG,"test1.txt open error \r\n"); 
        return;
    }
    int rsize = fread(read_buf, strlen(write_data),1,fd);
    printf("read %d data[%s]\r\n",rsize,read_buf);
    fclose(fd);
    remove(UFFS_MOUNT_POINT"/test1.txt");
}

void app_main(void)
{
    ESP_LOGI(TAG,"start app main \r\n");
    spi_nand_init();
    ESP_LOGI(TAG,"init_uffs start\r\n");

    const esp_vfs_uffs_conf_t conf = {
        .base_path = UFFS_MOUNT_POINT,
        .dont_mount = false,
        .format_if_mount_failed = false,
        .ops = nand_w25m01gvzeig_ops,
    }; 
    esp_err_t err = esp_vfs_uffs_register(&conf);
    if(err == ESP_OK)
        ESP_LOGI(TAG,"init_uffs ok\r\n");
    else
        ESP_LOGE(TAG,"init_uffs ERR\r\n");
    test_uffs();
    while (1) {
        // Add your main loop handling code here.
        vTaskDelay(1000);
    }
}
